from amscms import settings
from amscms.core.utils import navigation
from amscms.core.utils.request import render_to_response
from amscms.user_settings.forms import DeactivateForm
from amscms.user_settings.models import UserSettings
from django.contrib import messages
from django.contrib.auth.decorators import login_required
from django.contrib.auth.forms import PasswordChangeForm, PasswordResetForm, \
    SetPasswordForm
from django.contrib.auth.models import User
from django.contrib.auth.tokens import default_token_generator
from django.core.urlresolvers import reverse
from django.http import HttpResponseRedirect
from django.template.context import RequestContext
from django.utils.http import base36_to_int
from django.utils.translation import ugettext as _
from django.views.decorators.cache import never_cache
from django.views.decorators.csrf import csrf_protect
from forms import ProfileForm, NotificationForm

@csrf_protect
@login_required
def profile_update(request):
    navigation.breadcrumb(request, 'profile_update')
    context = {}
    
    if request.method == 'POST':
        form = ProfileForm(request.POST, instance=request.user)
        if form.is_valid():
            form.save()
            messages.success(request, _('Profile changed successfully.'))
            return HttpResponseRedirect("/settings/profile/")
        else:
            context["form"] = form
            return render_to_response(request, 'settings/profile.html', context)
    context["form"] = ProfileForm(instance=request.user) 
    return render_to_response(request, 'settings/profile.html', context)

@csrf_protect
@login_required
def notifications(request):
    navigation.breadcrumb(request, 'notifications')
    context = {}
    
    if request.method == 'POST':
        form = NotificationForm(request.POST)
        if form.is_valid():
            form.save(request.user)
            messages.success(request, _('Notifications updated successfully.'))
            return HttpResponseRedirect("/settings/notifications/")
        else:
            context["form"] = form
            return render_to_response(request, 'settings/notifications.html', context)
    
    # initial default message_notify value
    us, created = UserSettings.objects.get_or_create(user=request.user)
    if created:
        us.message_notify = True
        us.save()
    context["form"] = NotificationForm(initial = {'message_notify': us.message_notify})
    return render_to_response(request, 'settings/notifications.html', context)

@csrf_protect
@login_required
def deactivate(request):
    navigation.breadcrumb(request, 'deactivate')
    context = {}
    
    if request.method == 'POST':
        form = DeactivateForm(request.POST)
        if form.is_valid():
            form.save(current_user=request.user)
            messages.success(request, _('Your account deactivated successfully.'))
            from django.contrib.auth import logout
            logout(request)
            return HttpResponseRedirect(settings.LOGIN_URL)
    context["form"] = DeactivateForm()
    return render_to_response(request, 'settings/deactivate.html', context)
    
@csrf_protect
@login_required                    
def password_change(request, template_name='password/password_change_form.html',
                    post_change_redirect=None, password_change_form=PasswordChangeForm):
    navigation.breadcrumb(request, 'password_change')
    if post_change_redirect is None:
        post_change_redirect = reverse('amscms.user_settings.views.password_change_done')
    if request.method == "POST":
        form = password_change_form(user=request.user, data=request.POST)
        if form.is_valid():
            form.save()
            return HttpResponseRedirect(post_change_redirect)
    else:
        form = password_change_form(user=request.user)
    context = {}
    context['form'] = form    
    return render_to_response(request, template_name, context)
        
def password_change_done(request, template_name='password/password_change_done.html'):
    navigation.breadcrumb(request, 'password_change_done')
    return render_to_response(request, template_name, context_instance=RequestContext(request))

# 4 views for password reset:
# - password_reset sends the mail
# - password_reset_done shows a success message for the above
# - password_reset_confirm checks the link the user clicked and 
#   prompts for a new password
# - password_reset_complete shows a success message for the above

@csrf_protect
def password_reset(request, is_admin_site=False,
                   template_name='password/password_reset_form.html',
                   email_template_name='password/password_reset_email.html',
                   password_reset_form=PasswordResetForm,
                   token_generator=default_token_generator,
                   post_reset_redirect=None,
                   from_email=None,
                   current_app=None,
                   extra_context=None):
    navigation.breadcrumb(request, 'password_reset')
    if post_reset_redirect is None:
        post_reset_redirect = reverse('amscms.user_settings.views.password_reset_done')
    if request.method == "POST":
        form = password_reset_form(request.POST)
        if form.is_valid():
            opts = {
                'use_https': request.is_secure(),
                'token_generator': token_generator,
                'email_template_name': email_template_name,
            }
            if is_admin_site:
                opts = dict(opts, domain_override=request.META['HTTP_HOST'])
            form.save(**opts)
            return HttpResponseRedirect(post_reset_redirect)
    else:
        form = password_reset_form()
    context = {
        'form': form,
        'current_app': current_app,
    }    
    context.update(extra_context or {})
    return render_to_response(request, template_name, context)
    
def password_reset_done(request,
                        template_name='password/password_reset_done.html',
                        current_app=None, extra_context=None):
    navigation.breadcrumb(request, 'password_reset_done')
    context = {
        'current_app': current_app,
    }
    context.update(extra_context or {})
    return render_to_response(request, template_name, context)
            
# Doesn't need csrf_protect since no-one can guess the URL
@never_cache
def password_reset_confirm(request, uidb36=None, token=None,
                           template_name='password/password_reset_confirm.html',
                           token_generator=default_token_generator,
                           set_password_form=SetPasswordForm,
                           post_reset_redirect=None,
                           current_app=None, extra_context=None):    
    """
    View that checks the hash in a password reset link and presents a 
    form for entering a new password.
    """
    assert uidb36 is not None and token is not None # checked by URLconf
    if post_reset_redirect is None: 
        post_reset_redirect = reverse('amscms.user_settings.views.password_reset_complete')
    try:
        uid_int = base36_to_int(uidb36)
        user = User.objects.get(id=uid_int)
    except (ValueError, User.DoesNotExist):
        user = None
    
    if user is not None and token_generator.check_token(user, token):
        validlink = True
        if request.method == 'POST':
            form = set_password_form(user, request.POST)
            if form.is_valid():
                form.save()
                return HttpResponseRedirect(post_reset_redirect)
        else:
            form = set_password_form(None)
    else:
        validlink = False
        form = None
    context = {
        'form': form,
        'validlink': validlink,
    }
    context.update(extra_context or {})
    return render_to_response(request, template_name, context,
                              context_instance=RequestContext(request, current_app=current_app))    

def password_reset_complete(request,
                            template_name='password/password_reset_complete.html',
                            current_app=None, extra_context=None):
    navigation.breadcrumb(request, 'password_reset_complete')
    context = {
        'login_url': settings.LOGIN_URL,
    }
    context.update(extra_context or {})
    return render_to_response(request, template_name, context,
                              context_instance=RequestContext(request, current_app=current_app))
